" ==== 监控系统配置 ====
if !exists("s:monitor_bufnr")
    let s:monitor_bufnr = -1
endif

let s:max_log_lines = 1000  " 最大保留日志行数
let s:log_entries = []

" 固定高度模式 (单位：行)
" let g:deepseek#monitor_height = 15  " 窗口高度15行
" 百分比模式 (需用字符串)
" let g:deepseek#monitor_height = "30%"  " 占父窗口高度的30%
" 自动高度模式
let g:deepseek#monitor_height = "50%"    " 根据内容自动调整
let g:deepseek#monitor_direction = "botright"    " 根据内容自动调整
let g:deepseek#monitor_vertical = "vertical"   " 根据内容自动调整

" 创建专用缓冲区
function! deepseek#monitor#InitBuffer()
    call deepseek#log#debug("deepseek#monitor#InitBuffer()")
    let bufname = 'DeepseekMonitor'
    let s:monitor_bufnr = bufnr(bufname, 1)

    " 设置缓冲区属性（仅在首次创建时）
    if !bufloaded(s:monitor_bufnr)
        call setbufvar(s:monitor_bufnr, '&buftype', 'nofile')
        call setbufvar(s:monitor_bufnr, '&bufhidden', 'wipe')
        call setbufvar(s:monitor_bufnr, '&buflisted', 1)
        call setbufvar(s:monitor_bufnr, '&filetype', 'DeepseekMonitor')
    endif
    return s:monitor_bufnr
endfunction

" 获取或创建专用缓冲区
function! deepseek#monitor#GetBuffer()
    call deepseek#log#debug("deepseek#monitor#GetBuffer()")
    if s:monitor_bufnr < 0 || !bufexists(s:monitor_bufnr)
        call deepseek#log#debug("last monitor_bufnr = " .. s:monitor_bufnr)
        let s:monitor_bufnr = deepseek#monitor#InitBuffer()
    endif
    call deepseek#log#debug("monitor_bufnr = " .. s:monitor_bufnr)
endfunction

" ==== 窗口切换 ====
function! deepseek#monitor#ToggleWindow()
    call deepseek#log#debug("deepseek#monitor#ToggleWindow()")
    " 保存原始上下文
    let curr_win = win_getid()
    call deepseek#log#debug("current window = " .. curr_win)
    let curr_buf = bufnr('%')
    call deepseek#log#debug("current buffer = " .. curr_buf)
    " 获取或创建 buffer
    call deepseek#monitor#GetBuffer()
    let switch_buffer_cmd = 'buffer ' . s:monitor_bufnr
    " 窗口管理逻辑
    if bufwinid(s:monitor_bufnr) == -1 
        let s:monitor_winid = deepseek#monitor#CreateWindow()
        call deepseek#log#debug("create window " .. s:monitor_winid)
        call deepseek#log#debug("switch buffer " .. switch_buffer_cmd)
        call win_execute(s:monitor_winid, switch_buffer_cmd)
        call deepseek#monitor#Render()
    else
        " call deepseek#log#debug("close window " .. s:monitor_winid)
        call deepseek#monitor#CloseWindow(s:monitor_winid)
    endif
    " 恢复原始上下文
    " call deepseek#log#debug("restore window " .. curr_win)
    call win_gotoid(curr_win)
    " call deepseek#log#debug("restore buffer " .. curr_buf)
    execute 'buffer ' . curr_buf
endfunction

" ==== 窗口创建 ====
function! deepseek#monitor#CreateWindow()
    " call deepseek#log#debug("deepseek#monitor#CreateWindow()")
    " 配置解析
    let height = get(g:, 'deepseek#monitor_height', 20)
    let direction = get(g:, "deepseek#monitor_direction", "botright")
    let vertical = get(g:, "deepseek#monitor_vertical", "vertical")
    " 构建分割命令
    if type(height) == v:t_string
        if height ==# 'auto'
            let height = '' 
        endif
    else
        let height = string(height)
    endif
    let split_cmd = printf('keepalt %s %s %s split', direction, vertical, height)
    " call deepseek#log#debug("create window command: " . split_cmd) 
    " 创建窗口
    execute split_cmd
    let s:monitor_winid = win_getid()
    " 设置窗口属性
    setlocal winfixheight
    return s:monitor_winid
endfunction

function! deepseek#monitor#CloseWindow(winid)
    call win_execute(a:winid, "noautocmd close")
endfunction

" function! deepseek#monitor#SwitchBuffer()
"     let cmd = 'buffer ' . deepseek#monitor#GetBuffer() 
"     execute cmd
"     " 设置监控缓冲区属性
"     setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
"     setlocal filetype=DeepseekMonitor
"     " 自定义语法
"     syntax clear
"     syntax match DSRequest /^▶ Request.*/
"     syntax match DSResponse /^◀ Response.*/
"     highlight link DSRequest Special
"     highlight link DSResponse Identifier
"     " 自动滚动
"     autocmd BufAdd <buffer> normal! G
"     autocmd BufEnter <buffer> if g:deepseek#monitor_height == "auto" | resize | endif
"     call deepseek#monitor#Render()
" endfunction

" ==== 日志记录函数 ====
function! deepseek#monitor#Log(type, data)
    call deepseek#log#debug(printf("deepseek#monitor#Log(%s, %s)", a:type, a:data))
    call deepseek#log#debug("before add entry: s:log_entries = " .. string(s:log_entries))
    let entry = {
                \ 'time': strftime('%H:%M:%S'),
                \ 'type': a:type,
                \ 'data': a:data
                \ }

    " 维护日志队列
    call add(s:log_entries, entry)
    call deepseek#log#debug("after add entry: s:log_entries = " .. string(s:log_entries))
    if len(s:log_entries) > s:max_log_lines
        " call remove(s:log_entries, 0)
    endif

    if bufexists(s:monitor_bufnr)
        " call deepseek#log#debug("s:log_entries = " .. string(s:log_entries))
        call deepseek#monitor#Render()
        " call remove(s:log_entries, 0)
        " call deepseek#log#debug("s:log_entries = " .. string(s:log_entries))
    endif
endfunction

" ==== 日志渲染器 ====
function! deepseek#monitor#Render()
    call deepseek#log#debug("deepseek#monitor#Render()")
    if !bufexists(s:monitor_bufnr) | return | endif
    " 阶段1：准备数据（在安全上下文外完成）
    let lines = []
    for entry in s:log_entries[-100:]  " 仅显示最近100条
        call add(lines, printf('[%s] %s', entry.time, entry.type))
        call add(lines, '─'->repeat(80))

        if entry.type ==# 'REQUEST'
            call add(lines, 'Endpoint: ' . g:deepseek#api_endpoint)
            call add(lines, 'Headers:')
            call add(lines, '  Authorization: Bearer ****' . strpart(entry.data.headers.Authorization, -4))
            call add(lines, 'Payload:')
            call add(lines, '  ' . substitute(json_encode(entry.data.payload), "\n", ' ', 'g'))
        else
            call add(lines, 'Status: ' . entry.data.status)
            call add(lines, 'Headers:')
            for [k,v] in items(entry.data.headers)
                call add(lines, '  ' . k . ': ' . v)
            endfor
            call add(lines, 'Body:')
            call add(lines, '  ' . substitute(entry.data.body, "\n", "\n  ", 'g'))
        endif

        call add(lines, '')
    endfor
    call deepseek#log#debug("lines = " .. join(lines, "\n"))
    " 阶段2：延迟写入（通过定时器进入安全上下文）
    call timer_start(0, {-> s:SafeBufferUpdate(lines)})
endfunction

function! deepseek#monitor#GetLogEntries()
    if exists("s:log_entries")
        return s:log_entries
    else
        return []
    endif
endfunction

function! s:SafeBufferUpdate(lines)
    call deepseek#log#debug(printf("s:SafeBufferUpdate(lines = [%s] ) ", join(a:lines, "\n")))
    if !s:IsSafeContext() | return | endif
    let win_view = winsaveview()
    setlocal modifiable
    " 更新缓冲区内容
    silent execute '1,' . line('$') . 'delete'
    call setline(1, a:lines)
    setlocal nomodifiable
    call winrestview(win_view)
endfunction

function! s:IsSafeContext()
    " 检测是否在可修改的上下文中
    if mode() !~# '[ni]' | return 0 | endif
    " 检查是否在异步回调上下文
    if exists('*getcallbackinfo') && !empty(getcallbackinfo())
        return 0
    endif
    " 确认当前窗口可操作
    if !bufexists(s:monitor_bufnr) || !win_gotoid(bufwinid(s:monitor_bufnr))
        return 0
    endif
    return 1
endfunction
